

local Element = commonlib.getfield("Window.Elements.Element");

local ContextMenu = commonlib.inherit(Element);

ContextMenu:Property("Blockly");        -- 所属图块
ContextMenu:Property("TargetUI");       -- 目标UI
ContextMenu:Property("TargetPoint");    -- 目标点
ContextMenu:Property("MenuItemList");   -- 菜单项列表
ContextMenu:Property("HoverMenuItemIndex"); -- 悬浮菜单项索引

local ContextMenuWidth = 200;
local ContextMenuLineHeight = 30;

function ContextMenu:Init(blockly)
    self:SetBlockly(blockly);

    self:InitElement({
        name = "BlocklyContextMenu",
        attr = {
            style = "position: absolute; left: 0px; top: 0px; width: 0px; height: 0px;",
        },
    }, blockly:GetWindow(), blockly);

    self:SetTargetPoint({0, 0});
    self:SetMenuItemList({});
    self:SetHoverMenuItemIndex(0);
    self:SetExist(false);

    return self;
end

function ContextMenu:OnUpdateLayout()
    local menuitems = self:GetMenuItemList();
    local size = #menuitems;

    local width = ContextMenuWidth;
    local height = size * ContextMenuLineHeight;
    local point = self:GetTargetPoint();
    self:GetLayout():SetPos(point[1], point[2]);
    self:GetLayout():SetWidthHeight(width, height);
end

function ContextMenu:Render()
    local menuitems = self:GetMenuItemList();
    local size = #menuitems;
    local blockly = self:GetBlockly();

    if (size == 0) then return end 
    local x, y, w, h = self:GetPosition();

    -- background
    blockly:SetBrushColor(0x383838ff);
    blockly:DrawRectangle(x, y, w, h);

    -- hover 
    local hoverMenuItemIndex = self:GetHoverMenuItemIndex();
    if (1 <= hoverMenuItemIndex and hoverMenuItemIndex <= size) then
        blockly:SetBrushColor(0x285299ff);
        blockly:DrawRectangle(x, y + (hoverMenuItemIndex - 1) * ContextMenuLineHeight, w, ContextMenuLineHeight);
    end 

    -- text
    local padding = 20;
    blockly:SetPenColor(0xffffffff);
    for i, menuitem in ipairs(menuitems) do
        blockly:DrawText(x + padding, y + (i - 1) * ContextMenuLineHeight, w - 2 * padding, ContextMenuLineHeight, menuitem[1]);
    end
end

-- function ContextMenu:GetHoverIndex(event)
--     local menuitems = self:GetMenuItemList();
--     local size = #menuitems;
--     local x, y = self:ScreenXYToElementXY(event:GetXY());
--     return math.max(0, math.min(size, math.ceil(y / ContextMenuLineHeight)));
-- end

function ContextMenu:OnMouseDown(event)
    event:Accept();
    self:CaptureMouse();
end

function ContextMenu:OnMouseMove(event)
    event:Accept();
    local x, y = self:ScreenXYToElementXY(event:GetXY());
    self:SetHoverMenuItemIndex(math.ceil(y / ContextMenuLineHeight));
end

function ContextMenu:OnMouseUp(event)
    event:Accept();
    self:ReleaseMouse();
    self:Hide();

    local menuitems = self:GetMenuItemList();
    local size = #menuitems;
    local hoverMenuItemIndex = self:GetHoverMenuItemIndex();
    if (1 <= hoverMenuItemIndex and hoverMenuItemIndex <= size) then
        local targetUI = self:GetTargetUI();
        if (targetUI) then targetUI:OnContextMenuItem(menuitems[hoverMenuItemIndex]) end 
    end
end

function ContextMenu:Show(menuItemList, targetPoint, targetUI)
    self:SetMenuItemList(menuItemList);
    self:SetTargetPoint(targetPoint);
    self:SetTargetUI(targetUI);

    self:CaptureMouse();
    return ContextMenu._super.Show(self);
end

return ContextMenu;